
using System;
using System.IO;
using IrrlichtNETCP;
using IrrlichtNETCP.Inheritable;
using Gtk;
using GtkSourceView;

namespace kinematix
{
	public class kPythonEditor
	{
		
		SourceView text_box;
		TextView output_text;
		kApplication app;
		Expander exp;
		Window win;
		VBox vbox;		
		
		bool changed = false;
		bool new_script = true;
		string basedir = AppDomain.CurrentDomain.BaseDirectory;
		string fname;
		
		kPythonInterpreter python;

		public kPythonEditor (kApplication _app)
		{
		
			
			app = _app;
			python = app.PythonEngine;
			if (python == null) return;
			
		ActionEntry[] entries = new ActionEntry[] {
			new ActionEntry ("Menu1Action", null, "File", null, null, null),
			new ActionEntry("save-file", Stock.Save, "Save", "<control>S", "Save", tlbSave_OnClick),
			new ActionEntry("saveas-file", Stock.Save, "Save as", "", "Save as", OnSaveAs),			
			new ActionEntry("open-file", Stock.Open, "Open", "<control>O", "Open", tlbOpen_OnClick),
			new ActionEntry("new-file", Stock.New, "New", "<control>N", "New", tlbNew_OnClick),
			new ActionEntry("run-script", Stock.MediaPlay, "Run", "<control>F5", "Run", tlbRun_OnClick)			
			};
		
	
		string ui_info = 
			"	<menubar>" +
			"    <menu name=\"File\" action=\"Menu1Action\">\n" +
			"      <menuitem name=\"New\" action=\"new-file\" />\n" +			
			"      <menuitem name=\"Save\" action=\"save-file\" />\n" +
			"      <menuitem name=\"Save as\" action=\"saveas-file\" />\n" +			
			"      <menuitem name=\"Open\" action=\"open-file\" />\n" +			
			"    </menu>\n" +
			"	</menubar>\n" +
			"	<toolbar name=\"toolbar\">\n" +
			"		<toolitem name=\"new\" action=\"new-file\" />\n" +			
			"		<toolitem name=\"save\" action=\"save-file\" />\n" +
			"		<toolitem name=\"open\" action=\"open-file\" />\n" +
			"    <separator name=\"sep10\" />\n" +
			"		<toolitem name=\"run\" action=\"run-script\" />\n" +			
			"	</toolbar>\n";
		
	
		
			fname = "untitled.py";
			app = _app;
			//en.Globals.Add ("world", app.World);
			//en.Globals.Add ("app", app);

			win = new Gtk.Window ("Python script: "+fname);
			win.SetSizeRequest (400,600);
			
			win.DeleteEvent += win_OnDeleteEvent;
		
			vbox = new VBox ();
			win.Add (vbox);			
			
		ActionGroup group = new ActionGroup ("PythonInterpreter");
		group.Add(entries);			
			
		UIManager ui = new UIManager();
		ui.AddWidget += new AddWidgetHandler (OnWidgetAdd);
		ui.InsertActionGroup(group,0);
		ui.AddUiFromString(ui_info);	
		
		win.AddAccelGroup(ui.AccelGroup);

			exp = new Expander("Script output");
			ScrolledWindow scrl2 = new ScrolledWindow ();
			output_text = new TextView ();
			output_text.SetSizeRequest (400, 100);
			scrl2.Add (output_text);			
			exp.Add(scrl2);			
			vbox.PackEnd (exp, false, true, 0);
			
			ScrolledWindow scrl1 = new ScrolledWindow ();
			text_box = new SourceView (CreateBuffer ());
			text_box.ShowLineNumbers = true;
			scrl1.Add (text_box);
			vbox.PackEnd (scrl1);
			
			win.ShowAll ();
			
			
			
		}
		
		SourceBuffer CreateBuffer ()
		{
			SourceLanguagesManager manager = new SourceLanguagesManager ();

			SourceLanguage lang = manager.GetLanguageFromMimeType ("text/x-python");

			SourceBuffer buffer = new SourceBuffer (lang);
			buffer.Text = @"";
			buffer.Highlight = true;

			return buffer;
		}		
		
		public void win_OnDeleteEvent (object obj, System.EventArgs args)
		{
		}
		
		public void LoadFile(string aname)
		{
			try{
				fname = aname;
				StreamReader str = File.OpenText(aname);
				text_box.Buffer.Text = str.ReadToEnd();
				str.Close();
				win.Title = "Python script: "+Path.GetFileName(fname);
				new_script = false;
			} catch (IOException exc)
			{
				Console.WriteLine("No such file, "+exc.Message);
			}
		}
		
		public void tlbNew_OnClick (object obj, System.EventArgs args)
		{
			if (!new_script)
			{
			Dialog dlg = new Dialog("Create new?", win, DialogFlags.DestroyWithParent,
											"Cancel",ResponseType.Cancel,
                                      				"Yes",ResponseType.Accept);
		   	if (dlg.Run () == (int)ResponseType.Accept) 
			{
				NewScript ();
			}
				dlg.Destroy();
				return;
			}
			
			NewScript ();
		
		}
		
		public void NewScript ()
		{
			new_script = true;
			text_box.Buffer.Clear ();
			fname = "untitled.py";
			win.Title = "Python script: "+fname;
		}
	
		public void tlbRun_OnClick (object obj, System.EventArgs args)
		{
			try{
				python.Run(text_box.Buffer.Text);
			}
			catch ( Exception exc)
			{
				output_text.Buffer.Clear();
				output_text.Buffer.Text += "Error! "+exc.Message+"\n";
				exp.Expanded = true;
				Timeout.Add(5000, Expander_Close);
			}
		}
		
		public void SaveScript(string file)
		{
		       	StreamWriter str = File.CreateText(file);
				str.Write(text_box.Buffer.Text);
				str.Close();
		}
		
		public void OnSaveAs(object obj, System.EventArgs args)
		{
			Gtk.FileChooserDialog dlg = new FileChooserDialog("Save script",
													 null, FileChooserAction.Save,
												"Cancel",ResponseType.Cancel,
                                      				"Save",ResponseType.Accept);													 
			dlg.SetCurrentFolder(basedir+"/python");
			FileFilter fl = new FileFilter();
			fl.Name = "Python Scripts";
			fl.AddMimeType("text/x-python");
			dlg.AddFilter(fl);
			dlg.CurrentName = fname;
		   	if (dlg.Run() == (int)ResponseType.Accept) 
			{
				fname = dlg.Filename;
				SaveScript(fname);				
				win.Title = "Python script: "+Path.GetFileName(fname);
				new_script = false;				
          	}
          	dlg.Destroy();			
		}

		public void tlbSave_OnClick (object obj, System.EventArgs args)
		{
			if (new_script)
			{
				OnSaveAs(obj, args);
          	} else {
				SaveScript(fname);
          	}
	
		}
		
		public void tlbOpen_OnClick (object obj, System.EventArgs args)
		{
			Gtk.FileChooserDialog dlg = new FileChooserDialog("Открыть скрипт",
													 null, FileChooserAction.Open,
												"Отмена",ResponseType.Cancel,
                                      				"Открыть",ResponseType.Accept);													 
			dlg.SetCurrentFolder(basedir+"/python");
			//dlg.CurrentName = "untitled.py";
			FileFilter fl = new FileFilter();
			fl.Name = "Python scripts";
			fl.AddMimeType("text/x-python");
			dlg.AddFilter(fl);
			if (dlg.Run() == (int)ResponseType.Accept) 
			{
				fname = dlg.Filename;
				StreamReader str = File.OpenText(dlg.Filename);
				text_box.Buffer.Text = str.ReadToEnd();
				str.Close();
				win.Title = "Python script: "+Path.GetFileName(fname);
				new_script = false;
          	}
          	dlg.Destroy();
	
		}		
		
		public bool Expander_Close()
		{
			exp.Expanded = false;
			return false;
		}
		
		
		void OnWidgetAdd (object obj, AddWidgetArgs args)
		{
			vbox.PackStart (args.Widget, false, true, 0);		
		}	
	}
}
